package com.py.framework.common;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.py.framework.service.MenuResourceService;
import com.py.framework.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.py.framework.core.common.URLConstants;
import com.py.framework.core.helper.HttpServletHelper;
import com.py.framework.core.log.ExceptionLogger;
import com.py.framework.core.utils.SerializingUtil;
import com.py.framework.entity.LogEntity;
import com.py.framework.entity.UserEntity;
import com.py.framework.service.SysLogService;

/**
 * 日记记录AOP实现
 *
 * @author Leegern
 * @date 2018年5月10日
 */
@Component
@Aspect
public class SysLogAspect {

    /**
     * 系统日志Service
     **/
    @Autowired
    private SysLogService sysLogService;
    /**
     * 用户Service
     **/
    @Autowired
    private UserService userService;

    @Autowired
    private MenuResourceService menuResourceService;

    /**
     * 切入方法
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("execution(* com.py.framework.controller.*.*(..))")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;
        try {
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = servletRequestAttributes.getRequest();
            // 获取请求地址
            String requestPath = request.getRequestURI();
            String servletPath = request.getServletPath();

            if (StringUtils.isBlank(servletPath)) {
                String ctxPath = request.getContextPath();
                servletPath = requestPath.replaceFirst(ctxPath, "");
            }

            //判断URL是否存入日志
            if (URLConstants.LOGIN_URL.equals(servletPath) || URLConstants.LOGOUT_URL.equals(servletPath) || menuResourceService.getMenuNameByLinkURL(servletPath) != null) {
                if (!URLConstants.POST_LOG_URL.equals(servletPath)) {
                    LogEntity entity = new LogEntity();
                    String jdToken = HttpServletHelper.getUserToken(request);
                    if (StringUtils.isNotBlank(jdToken)) {
                        byte[] bts = UserCacheHelper.getUserFromCache(SerializingUtil.serialize(jdToken));
                        if (null != bts && bts.length > Constants.NUMBER_ZERO) {
                            UserEntity user = (UserEntity) SerializingUtil.deserialize(bts);
                            if (null != user) {
                                //如果有用户名，传入用户名
                                if (null != user.getUsername() && user.getUsername().length() > Constants.NUMBER_ZERO) {
                                    entity.setUsername(user.getUsername());
                                    entity.setRealName(user.getRealName());
                                }
                            }
                        }
                    }
                    // 用户登录或退出地址
                    if (URLConstants.LOGIN_URL.equals(servletPath)) {
                        //用户登录根据链接获取用户名
                        String requestParams = HttpServletHelper.getRequestParams(request);
                        String[] requestArr = requestParams.split("&");
                        Map<String, String> urlMap = new HashMap<>();
                        for (String str : requestArr) {
                            String strKey = str.split("=")[0];
                            String strValue = str.split("=")[1];
                            urlMap.put(strKey, strValue);
                        }
                        entity.setUsername(urlMap.get("username"));
                        List<UserEntity> userEntities = userService.getUsersByUsername(urlMap.get("username"));
                        entity.setRealName(userEntities.get(0).getRealName());
                        entity.setLogType(Constants.NUMBER_TWO);
                        entity.setRequestDesc("用户登录");
                    } else if (URLConstants.LOGOUT_URL.equals(servletPath)) {
                        entity.setLogType(Constants.NUMBER_THREE);
                        entity.setRequestDesc("用户登出");
                    } else {
                        entity.setLogType(Constants.NUMBER_ONE);
                        //根据servletPath查询jd_sys_menu_resource中MENU_NAME
                        String menuName = menuResourceService.getMenuNameByLinkURL(servletPath).getMenuName();
                        entity.setRequestDesc(menuName);
                    }
                    entity.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    entity.setUpdateTime(new Timestamp(System.currentTimeMillis()));
                    entity.setDelFlag(Constants.NUMBER_ONE);
                    entity.setRequestContent(HttpServletHelper.getRequestParams(request));
                    entity.setRequestIp(HttpServletHelper.getGuestIP(request));
                    entity.setRequestUrl(requestPath);
                    entity.setShortRequestUrl(servletPath);

                    // 日志存入缓冲队列
                    sysLogService.sendToQueue(entity);
                }
            }
        } catch (Exception e) {
            ExceptionLogger.error(e);
        } finally {
            // 执行完方法的返回值：调用processd方法，就会触发切入点方法执行
            result = joinPoint.proceed();
        }
        return result;

    }
}